﻿#include "Hero.h"
#include "bullet/Bullet.h"
#include "bullet/BulletFactory.h"
#include "bullet/BulletManager.h"
#include "cocostudio/CocoStudio.h"
#include "utils/AudioUtil.h"
using namespace cocos2d;
using namespace cocos2d::ui;
using namespace cocostudio::timeline;
Hero::Hero():
	isMove(true),
	invincibleState(false),
	isMoveing(false),
	//bulletCount(3),
	onTouchBeganCall(nullptr),
	onTouchEndedCall(nullptr),
	live(true),
	isPerformWonders(false)
{

}
Hero* Hero::create() {
	Hero* ret = new (std::nothrow) Hero();
	if (ret && ret->init()) {
		ret->autorelease();
		return ret;
	}
	CC_SAFE_DELETE(ret);
	return nullptr;
}
Hero* Hero::pInstance = nullptr;

bool Hero::init() {
	if (!Widget::init()) {
		return false;
	}
	loadUserInfo();
	initCSBFile();
	initHero();
	initWeapon();
	openTouchListener();
	initBulletCountArr();
	return true;
}


/*
	加载用户信息
*/
void Hero::loadUserInfo() {
	int heroTempBulletCount = UserDefault::getInstance()->getIntegerForKey("shesu_value", 10);
	int heroTempAtk = UserDefault::getInstance()->getIntegerForKey("huoli_value", 10);
	bulletCount = heroTempBulletCount / 10;
	atk = heroTempAtk / 5;
	strengthenATK = atk * 3;

	int weaponTempBulletSpeed = UserDefault::getInstance()->getIntegerForKey("strength_value", 10);
	int weaponTempBulletAtk = UserDefault::getInstance()->getIntegerForKey("weaponHuoli_value", 10);
	weaponShesu = weaponTempBulletSpeed / 15.0;
	weaponAtk = weaponTempBulletAtk / 3;
}

/*
	加载CSB文件
*/
void Hero::initCSBFile() {
	size = Director::getInstance()->getVisibleSize();
	int select = UserDefault::getInstance()->getIntegerForKey("selected", 0);
	filename[40];
	sprintf_s(filename, "scenes/publicUi/hero_%d.csb", select);
	//加载csb文件
	root = CSLoader::createNode(filename);
	this->addChild(root);
}

/*
	初始化主机
*/
void Hero::initHero() {
	hero = dynamic_cast<Sprite*>(root->getChildByName("hero_body"));
	ActionTimeline* heroAct = CSLoader::createTimeline(filename);
	////播放某个动作 参数：1.动作的名字 2.是否循环
	heroAct->play("spray", true);
	////指定节点播放动作
	root->runAction(heroAct);
	heroSize = hero->getContentSize();
}

/*
	初始化僚机
*/
void Hero::initWeapon() {
	weapon_left = dynamic_cast<Sprite*>(hero->getChildByName("hero_weapon_left"));
	weapon_right = dynamic_cast<Sprite*>(hero->getChildByName("hero_weapon_right"));
	
	weaponSize = weapon_left->getContentSize();
}
/*
	开启触摸监听
*/
void Hero::openTouchListener() {
	EventListenerTouchOneByOne* eventListener = EventListenerTouchOneByOne::create();
	eventListener->onTouchBegan = CC_CALLBACK_2(Hero::onTouchBegan, this);
	eventListener->onTouchMoved = CC_CALLBACK_2(Hero::onTouchMoved, this);
	eventListener->onTouchEnded = CC_CALLBACK_2(Hero::onTouchEnded, this);
	_eventDispatcher->addEventListenerWithSceneGraphPriority(eventListener, this);
}

/*
	当触摸开始时，要执行的函数
*/
bool Hero::onTouchBegan(Touch* touch, Event* event) {
	if (onTouchBeganCall != nullptr && isMove) {
		onTouchBeganCall();//函数指针(实参表)
	}
	Vec2 touchPoint = this->convertTouchToNodeSpace(touch);
	bool isContain = hero->boundingBox().containsPoint(touchPoint);
	if (isContain) {
		return true;
	}
	return false;
}

/*
	当触摸移动时，要执行的函数
*/
void Hero::onTouchMoved(Touch* touch, Event* event) {
	if (isMove) {
		isMoveing = true;
		//获取当前移动的值
		Vec2 pos = this->convertTouchToNodeSpace(touch);

		//判断飞机的位置应该在(0-540)之间
		if (pos.x >= size.width / 2 - heroSize.width / 2) {
			pos = Vec2(size.width / 2 - heroSize.width / 2, pos.y);
		} else if (pos.x <= -(size.width / 2) + heroSize.width / 2) {
			pos = Vec2(-(size.width / 2) + heroSize.width / 2, pos.y);
		}

		//判断飞机的y轴可移动的值应该在(0-960)之间
		if (pos.y >= size.height / 10 * 7 - heroSize.height / 2) {
			pos = Vec2(pos.x, size.height / 10 * 7 - heroSize.height / 2);
		} else if (pos.y <= -size.height / 10 * 3 + heroSize.height / 2) {
			pos = Vec2(pos.x, -size.height / 10 * 3 + heroSize.height / 2);
		}
		hero->setPosition(pos);
		//root->setPosition(pos);
		heroPos = pos;
	} else {
		onTouchEndedCall();
	}
}

/*
	当触摸取消时，要执行的函数
*/
void Hero::onTouchEnded(Touch* touch, Event* event) {
	isMoveing = false;
	if (onTouchEndedCall != nullptr) {
		onTouchEndedCall();//函数指针(实参表)
	}
}



/*
	创建子弹
*/
void Hero::createBullet(int posX) {
	//创建子弹
	Bullet* bullet = BulletFactory::createBullet();
	AudioUtil::getInstence()->heroShoottSound();
	bullet->setZOrder(2);
	float h = heroSize.height / 2;
	float x = hero->getPositionX() + getPositionX() + posX;
	float y = hero->getPositionY() + getPositionY() + h;
	//设置子弹的位置:英雄的坐标 + 英雄图片高度的一半
	bullet->setPosition(Vec2(x,y));

	_parent->addChild(bullet);

	BulletManager::getInstance()->addHeroBullet(bullet);
}

/*
	创建僚机子弹
*/
void Hero::createWeaponBullet() {
	float h = weaponSize.height / 4;
	float x;
	float y = hero->getPositionY() / 2 + getPositionY() + h + 20;
	int flag = 1;
	for (int i = 0; i < 2; i++) {
		flag *= -1;
		//创建僚机子弹 一左一右
		Bullet* leftBullet = BulletFactory::createBullet(WeaponBullet);
		leftBullet->setZOrder(2);
		x = hero->getPositionX() + getPositionX() + 42 * flag;
		leftBullet->setPosition(Vec2(x, y));
		_parent->addChild(leftBullet);
		BulletManager::getInstance()->addHeroBullet(leftBullet);
	}
}

/*
	开启或关闭射击调度器
*/
void Hero::isOpenShoot(bool result, float delay) {
	if (result) {
		schedule(schedule_selector(Hero::shootUpdate), 0.1, -1, delay);
		schedule(schedule_selector(Hero::weaponShootUpdate), 3 - weaponShesu, -1, delay);
	} else {
		unschedule(schedule_selector(Hero::shootUpdate));
		unschedule(schedule_selector(Hero::weaponShootUpdate));
	}
}

/*
	射击调度器
*/
void Hero::shootUpdate(float dt) {
	for (int i = 0; i < bulletCount; i++) {
		createBullet(bulletCountArr[i]);
	}
}

/*
	僚机射击调度器
*/
void Hero::weaponShootUpdate(float dt) {
	createWeaponBullet();
}

/*
	根据子弹数量初始化子弹位置
*/
void Hero::initBulletCountArr() {
	int temp = bulletCount;
	int flag = 1;
	int dis = 15;
	int left = 0, right = bulletCount - 1;
	while (left < right) {
		bulletCountArr[left++] = temp / 2 * dis * -flag;
		bulletCountArr[right--] = temp / 2 * dis * flag;
		temp -= 2;
	}
	if (left >= right && bulletCount%2 == 1) {
		bulletCountArr[bulletCount / 2] = 0;
	}
	
}

/*
	回收自己
*/
void Hero::collectionHero() {
	pInstance = nullptr;
	this->removeFromParent();
}

/*
	主机死亡
*/
void Hero::die() {
	hero->setVisible(false);
	live = false;
	isOpenShoot(false);
	dieSp = dynamic_cast<Sprite*>(root->getChildByName("herodie"));
	dieSp->setVisible(true);
	ActionTimeline* heroAct = CSLoader::createTimeline(filename);
	heroAct->play("die", false);
	heroAct->setAnimationEndCallFunc("die", [this]() {
		//回收自己
		//collectionHero();
	});
	root->setPosition(heroPos);
	root->runAction(heroAct);
}

/*
	返回自己的矩形
*/
Rect Hero::getHeroRect() {
	float x = convertToWorldSpace(heroPos).x - 50;
	float y = convertToWorldSpace(heroPos).y;
	float width = heroSize.width / 3 * 2;
	float height = heroSize.height / 3 * 2;
	return Rect(x, y, width, height);
}

/*
	是否强化射速
*/
void Hero::isEnhancedRateOfFire(bool flag) {
	if (flag) {
		bulletCount = 11;
		initBulletCountArr();
	} else {
		int heroTempBulletCount = UserDefault::getInstance()->getIntegerForKey("shesu_value", 10);
		bulletCount = heroTempBulletCount / 10;
		initBulletCountArr();
	}
}

/*
	是否强化火力
*/
void Hero::isEnhancedFirepower(bool flag) {
	if (flag) {
		atk = strengthenATK;
	} else {
		int heroTempAtk = UserDefault::getInstance()->getIntegerForKey("huoli_value", 10);
		atk = heroTempAtk / 5;
	}
}